package com.playfair.components;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;

import com.playfair.core.AppCore;

public class Matrix {

	private final Integer size = 5, n = size * size;
	private final String key;
	private final Character[][] playFairMatrix;
	private final HashMap<Character, Integer[]> mainMatrix;

	public Matrix(String key) {
		key = key.toUpperCase();
		this.key = key.replaceAll("\\s", "");
		playFairMatrix = new Character[size][size];
		mainMatrix = new HashMap<Character, Integer[]>();
		generatePlayfairMatrix();
		// printMatrix();
	}

	public Matrix() {
		this.key = "";
		playFairMatrix = new Character[size][size];
		mainMatrix = new HashMap<Character, Integer[]>();
		generateRandomMatrix();
	}

	private void generateRandomMatrix() {
		ArrayList<Character> letters = new ArrayList<Character>();
		for (Character i = 'A'; i <= 'Z'; i++) {
			if (i.equals(AppCore.getInstance().getInterchangeChar1()))
				continue;
			letters.add(i);
		}
		Random random = new Random();
		int j = 0;
		while (letters.size() > 0) {
			Character tmp = letters.get(random.nextInt(letters.size()));
			playFairMatrix[j / 5][j % 5] = tmp;
			letters.remove(tmp);
			j++;
		}
		for (int i = 0; i < n; i++) {
			Integer[] tmp = new Integer[2];
			tmp[0] = i / 5;
			tmp[1] = i % 5;
			mainMatrix.put(playFairMatrix[i / 5][i % 5], tmp);
		}
		letters = null;
	}

	private void generatePlayfairMatrix() {
		ArrayList<Character> letters = new ArrayList<Character>();
		for (Character i = 'A'; i <= 'Z'; i++) {
			if (i.equals(AppCore.getInstance().getInterchangeChar1()))
				continue;
			letters.add(i);
		}
		int j = key.length();
		boolean pass = true;
		for (int i = 0; i < n; i++) {
			if (pass && j != 0) {
				Character tmp = key.charAt(key.length() - j--);
				// System.out.println(tmp);
				if (tmp.equals(AppCore.getInstance().getInterchangeChar1())) {
					tmp = AppCore.getInstance().getInterchangeChar2();
				}
				if (letters.contains(tmp)) {
					playFairMatrix[i / 5][i % 5] = tmp;
					letters.remove(new Character(tmp));
				} else {
					i--;
				}
			} else {
				pass = false;
				playFairMatrix[i / 5][i % 5] = letters.get(j++);
			}
		}
		for (int i = 0; i < n; i++) {
			Integer[] tmp = new Integer[2];
			tmp[0] = i / 5;
			tmp[1] = i % 5;
			mainMatrix.put(playFairMatrix[i / 5][i % 5], tmp);
		}
		letters = null;
	}

	public void printMatrix() {
		for (int i = 0; i < n; i++) {
			System.out.print(playFairMatrix[i / 5][i % 5]);
			if (i % 5 == 4)
				System.out.println();
		}
	}

	public int getSize() {
		return size;
	}

	public Character[][] getPlayFairMatrix() {
		return playFairMatrix;
	}

	public HashMap<Character, Integer[]> getMainMatrix() {
		return mainMatrix;
	}

	public String getKey() {
		return key;
	}

}
